/*!
 * Copyright (C) 2020 - All Rights Reserved by
 * @author : ZhaoYanbo
 * @email  : zyb920@hotmail.com
 * @created: 2020-10-31
 * @version: 1.0.0.0
 *
 */

#include "ListModel.h"
#include <QtDebug>

ListModel::ListModel(QObject *parent) : QAbstractListModel(parent)
{

}

ListModel::~ListModel()
{

}

int ListModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_data_list.length();
}

int ListModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return 1;
}

QVariant ListModel::data(const QModelIndex &index, int role) const
{
    const int row = index.row();
    if( isValid(row) )
    {
        auto *ptr = m_data_list.at(row);
        switch (role)
        {
        case HeadRole:
            return ptr->isHead;
        case ExpandRole:
            return ptr->isExpand;
        case NameRole:
            return ptr->name;
        default: break;
        }
    }
    return QVariant();
}

bool ListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    const int row = index.row();
    if ( isValid(row)  )
    {
        auto *ptr = m_data_list.at(row);
        switch (role)
        {
        case HeadRole:
            ptr->isHead = value.toBool();
            break;
        case ExpandRole:
        {
            bool old = ptr->isExpand;
            ptr->isExpand = value.toBool();
            if(old != ptr->isExpand) //发生了变化
            {
                if(ptr->isExpand) //把所有subs添加到父
                {
                    const int len1 = index.row();
                    const int len2 = ptr->subs.length();
                    beginInsertRows(QModelIndex(), len1, len1 + len2 - 1);
                    for(int i=0; i<len2; ++i)
                        m_data_list.insert(len1+i+1, ptr->subs[i]);
                    endInsertRows();
                }
                else //把所有subs从父中移除
                {
                    const int len1 = index.row();
                    const int len2 = ptr->subs.length();
                    beginRemoveRows(QModelIndex(), len1, len1 + len2 - 1);
                    for(int i=0; i<len2; ++i)
                        m_data_list.removeAt(len1+1);
                    endRemoveRows();
                }
            }
            break;
        }
        case NameRole:
            ptr->name = value.toString();
            break;
        default: break;
        }
        emit dataChanged(index, index);
        return true;
    }
    return false;
}

Qt::ItemFlags ListModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::NoItemFlags;

    if (index.data(HeadRole).toBool())
        return Qt::NoItemFlags;

    return QAbstractListModel::flags(index) | Qt::ItemIsEditable;
}

bool ListModel::isValid(int index) const
{
    if(index >= 0 && index < m_data_list.length() )
    {
        return true;
    }
    return false;
}

bool ListModel::append(Data *d)
{
    return insert(m_data_list.length(), d);
}

bool ListModel::append(QString name, bool head)
{
    Data *p = new Data;
    p->name = name;
    p->isHead = head;

    return append(p);
}

bool ListModel::insert(int index, Data *d)
{
    if (index >= 0  && index <= m_data_list.length())
    {
        beginInsertRows(QModelIndex(), index, index);
        m_data_list.insert(index, d);
        endInsertRows();

        return true;
    }
    return false;
}

Data *ListModel::get(int index)
{
    if( isValid(index) )
    {
        return m_data_list.at(index);
    }
    return nullptr;
}
